package com.example.redisdemo.controllerplus;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Service;

import java.util.Collections;

@Service
public class DistributedLockService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    public DistributedLockService(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 获取分布式锁
     * @param lockKey 锁的名称
     * @param requestId 请求标识，用于释放锁
     * @param expireTime 锁的过期时间
     * @return true表示获取锁成功，false表示获取锁失败
     */
    public boolean tryLock(String lockKey,String requestId,long expireTime) {
        String luaScript = "if redis.call('set',KEYS[1],ARGV[1],'NX','PX',ARGV[2]) then return 1 else return 0 end";
        RedisScript<Long> script = new DefaultRedisScript<>(luaScript,Long.class);
        Long result = redisTemplate.execute(script, Collections.singletonList(lockKey),requestId,String.valueOf(expireTime));
        return result != null && result ==1;
    }

    /**
     * 释放分布式锁
     * @param lockKey 锁的名称
     * @param requestId 请求标识
     * @return true标识锁释放成功，false表示锁释放失败
     */
    public boolean releaseLock(String lockKey,String requestId) {
        String luaScript = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
        RedisScript<Long> script = new DefaultRedisScript<>(luaScript, Long.class);
        Long result = redisTemplate.execute(script, Collections.singletonList(lockKey), requestId);
        return result != null && result ==1;
    }
}
